/**
 * 常用公共的方法
 * @author yangxiao
 * @module app/master/common-function
 */

import * as ws from 'ws';
import * as serverConfig from '../../lib/config/config'
import * as cws from '../../lib/net/client-websocket';
import * as sws from '../../lib/net/server-websocket';
import * as wsEvent from '../../lib/net/event-websocket';
import * as protobuf from '../../lib/protobuf/protobuf-msg';
import * as log from '../../lib/log/log'
import * as msgSend from '../../util/get-send-function';
import * as getGameServer from './plug-ins/get-client-gameserver';
import * as moduleRegister from './module-register';



/**
 * 发送到游戏服务器
 * @param {protoBufMsg.msg_base_s2s} msg_base_s2s
 */
export function sendGameServer(msg_base_s2s:protoBufMsg.msg_base_s2s){

    let client = getGameServer.base(_gameClients);
    msgSend.send(msg_base_s2s,client.getClient(),__filename);
}

/**
 * 发送到聊天服务器
 * @param {protoBufMsg.msg_base_s2s} msg_base_s2s
 */
export function sendChatServer(msg_base_s2s:protoBufMsg.msg_base_s2s){

    msgSend.send(msg_base_s2s,_chatClient.getClient(),__filename);
}


/**
 * 发送消息到客户端
 * 
 * @export
 * @param {any} sessionID 客户的唯一ID
 * @param {protoBufMsg.msg_base_s2c} msg_base_s2c
 */
export function sendClient(sessionID:string,msg_base_s2c:protoBufMsg.msg_base_s2c){

    msgSend.send(msg_base_s2c,_clientServer.getClient(sessionID),__filename,false);
}


/**
 * 停服
 * 
 * @export
 */
export function stopServer(){
    _clientServer.stop();
}


export let _clientServer:sws.ServerWebSocket;
export let _gameClients:cws.ClientWebSocket[];
export let _chatClient:cws.ClientWebSocket;

export function register(){

    let config = serverConfig.getServerConfig();
    if(_clientServer==null){
        _clientServer = new sws.ServerWebSocket();//负责前段数据处理
        _clientServer.createServer(config.serverMaster.clientPort);
        _clientServer.on(wsEvent.Event.clientMessage,_clientMessage);
    }
    if(_chatClient==null){
        _chatClient = new cws.ClientWebSocket();
        _chatClient.headers.serverid = serverConfig.serverID;
        _chatClient.Connection(config.serverChat.host,config.serverChat.port);
        _chatClient.on(wsEvent.Event.open,()=>{
            console.log(config.serverChat.id,'connection success');
        });
        _chatClient.on(wsEvent.Event.clientMessage,(msg)=>_otherServerMessage(msg));
    }
    if(_gameClients==null){
        _gameClients=[];
        let len = config.ServerGameList.length;
        
        for(let i=0;i<len;++i){
            let _gameclient = new cws.ClientWebSocket();
            _gameclient.headers.serverid =  serverConfig.serverID;
            _gameclient.Connection(config.ServerGameList[i].host,config.ServerGameList[i].port);
            _gameclient.on(wsEvent.Event.open,()=>{
                console.log(config.ServerGameList[i].id,'connection success');
            });
            _gameclient.on(wsEvent.Event.clientMessage,(msg)=>_otherServerMessage(msg));
            _gameClients.push(_gameclient);
        }
    }
}

export function _clientMessage(message:any,client:ws){ 
 
    try{
              
        let sessionID = (client.upgradeReq as any).sessionID;
        let classList = protobuf.getMsgProto();
 
        let msg_base_c2s = classList.msg_base_c2s.decode(message);
        
        switch(msg_base_c2s.getMsgType()){
             case protoBufMsg.msg_base_type.gameServer:
                let game_msg_base_s2s = new classList.msg_base_s2s();
                game_msg_base_s2s.setSessionID(sessionID);
                game_msg_base_s2s.setMsgType(protoBufMsg.msg_base_type.gameServer);
                game_msg_base_s2s.setMsgCode(msg_base_c2s.msg_code);
                game_msg_base_s2s.setMsg(msg_base_c2s.msg);
                sendGameServer(game_msg_base_s2s);
            break;
            case protoBufMsg.msg_base_type.masterServer:
                moduleRegister.excModuleMain(msg_base_c2s.msg_code,sessionID,msg_base_c2s);
            break;
             case protoBufMsg.msg_base_type.chatServer:
                let chat_msg_base_s2s = new classList.msg_base_s2s();
                chat_msg_base_s2s.setSessionID(sessionID);
                chat_msg_base_s2s.setMsgType(protoBufMsg.msg_base_type.chatServer);
                chat_msg_base_s2s.setMsgCode(msg_base_c2s.msg_code);
                chat_msg_base_s2s.setMsg(msg_base_c2s.msg);
                sendChatServer(chat_msg_base_s2s);
            break;
            case protoBufMsg.msg_base_type.client:
                //sendClient(sessionID,msg_base_c2s); 这里的需求在于调试，上线后不应该开放
            break;

        }
    }catch(e){
        client.close(1000,"error message Illegal format");
        return;
    }
}

export function _otherServerMessage(message){

    try{
        let classList = protobuf.getMsgProto();
        let msg_base_s2s = classList.msg_base_s2s.decode(message);
        let msg_base_s2c = new classList.msg_base_s2c();
        msg_base_s2c.setMsgCode(msg_base_s2s.msg_code);
        msg_base_s2c.setMsg(msg_base_s2s.msg.toArrayBuffer() as any);


        switch(msg_base_s2s.getMsgType()){
            case protoBufMsg.msg_base_type.client:
                sendClient(msg_base_s2s.sessionID,msg_base_s2c);
            break;
             case protoBufMsg.msg_base_type.gameServer:
                msg_base_s2s.setMsgType(protoBufMsg.msg_base_type.gameServer);
                sendGameServer(msg_base_s2s);
            break;
            case protoBufMsg.msg_base_type.masterServer:
                moduleRegister.excModuleMain(msg_base_s2s.msg_code,msg_base_s2s.sessionID,msg_base_s2c);
            break;
            case protoBufMsg.msg_base_type.chatServer:
                msg_base_s2s.setMsgType(protoBufMsg.msg_base_type.gameServer);
                sendChatServer(msg_base_s2s);
            break;

        }
    }catch(e){
        log.error("error otherServerMessage message Illegal format",e);
        return;
    }
}